import axios from 'axios'
import qs from 'qs'
import { useEmployeeStore } from '@/stores'
import { ref } from 'vue'
import { employeeRefreshTokenService } from '@/api/employee'

const baseURL = 'http://localhost:20243'

const instance = axios.create({
  baseURL, // 基础地址
  timeout: 300000 // 超时时间
})

// 请求拦截器
instance.interceptors.request.use(
  (config) => {
    const employeeStore = useEmployeeStore()
    const token = employeeStore.employeeInfo.token
    // 设置请求头
    if (token) {
      config.headers.token = token
    }

    return config
  },
  (err) => Promise.reject(err)
)

const refresh = ref(true)

// 响应拦截器
instance.interceptors.response.use(
  (response) => {
    // 业务成功
    if (response.data.flag) {
      return response.data
    }

    // 业务失败
    ElMessage.error(response.data.message || '服务异常')
    return Promise.reject(response.data)
  },
  async (error) => {
    // 系统失败
    const employeeStore = useEmployeeStore()

    // 登录失效，token过期
    if (error.response?.status === 401) {
      if (refresh.value) {
        // 不能再次刷新
        refresh.value = false
        const employeeInfo = employeeStore.employeeInfo
        const username = employeeInfo.username
        const refreshToken = employeeInfo.refreshToken

        // 尝试刷新token
        await employeeRefreshTokenService(username, refreshToken).then(
          (response) => {
            // 刷新成功
            employeeInfo.token = response.data.token
            employeeInfo.refreshToken = response.data.refreshToken
            employeeStore.setEmployeeInfo(employeeInfo)

            // 可以继续刷新
            refresh.value = true
          }
        )

        // todo 不会重新调用处理函数，此处仅能优化体验
        ElMessage.error('用户状态异常，请重试本次操作')

        return
      } else {
        // 刷新未成功，将再次返回401
        // 将能再次刷新refresh改为true
        refresh.value = true

        // 清除登录信息，跳转登录页
        employeeStore.removeEmployeeInfo()

        // 拦截器通常是用于处理 HTTP 请求和响应的逻辑，而不是用来直接执行页面跳转的
        // todo 我不会呀在其它地方跳转
        setTimeout(() => {
          window.location.href = '/login'
        }, 1500)
      }
    }

    ElMessage.error(
      // ?.可选链操作符（Optional Chaining）允许在尝试访问一个对象的深层属性时，
      // 如果中间的某个属性不存在，则整个表达式会立即返回undefined，而不是抛出一个错误
      error.response?.data.message || error.message || '服务异常'
    )

    // 返回reject，将不再执行请求代码后的操作
    return Promise.reject(error)
  }
)

// 创建一个发送 x-www-form-urlencoded 请求的函数
function post(url, data) {
  return instance.post(url, qs.stringify(data), {
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
    }
  })
}

export default instance
export { baseURL, post }
